package com.lonely.goods.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lonely.common.utils.SecurityUtils;
import com.lonely.goods.domain.dto.goods.GoodsQuotationSheetPartDTO;
import com.lonely.goods.domain.dto.goods.GoodsQuotationSheetPartProcessDTO;
import com.lonely.goods.domain.dto.goods.GoodsQuotationSheetSubmitDTO;
import com.lonely.goods.domain.entity.SysGoodsProcess;
import com.lonely.goods.domain.entity.SysGoodsProcessItem;
import com.lonely.goods.mapper.SysGoodsProcessMapper;
import com.lonely.goods.service.IGoodsProcessItemService;
import com.lonely.goods.service.IGoodsProcessService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author : 黄志标
 * @date: 2025/7/2 10:50
 * @description: 商品工序服务实现类
 */
@Service
public class GoodsProcessServiceImpl extends ServiceImpl<SysGoodsProcessMapper, SysGoodsProcess> implements IGoodsProcessService {

    @Autowired
    private IGoodsProcessItemService goodsProcessItemService;

    /**
     * 编辑商品报价单部件工序信息
     *
     * @param submitDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submitGoodsQuotationSheetPartsProcess(GoodsQuotationSheetSubmitDTO submitDTO) {
        if (CollUtil.isEmpty(submitDTO.getParts())) {
            return;
        }

        for (GoodsQuotationSheetPartDTO part : submitDTO.getParts()) {

            // 提交的工序配置
            GoodsQuotationSheetPartProcessDTO submitGoodsProcess = part.getPartProcess();

            // 查询当前部件对应的工序数据
            SysGoodsProcess sysGoodsProcess = super.getOne(new LambdaQueryWrapper<SysGoodsProcess>()
                    .eq(SysGoodsProcess::getGoodsId, submitDTO.getId())
                    .eq(SysGoodsProcess::getGoodsPartId, part.getPartId())
            );
            if (sysGoodsProcess == null) {
                // 新添加部件工序配置
                sysGoodsProcess = new SysGoodsProcess();
                sysGoodsProcess.setGoodsId(submitDTO.getId());
                sysGoodsProcess.setGoodsPartId(part.getPartId());
                sysGoodsProcess.setProfit(submitGoodsProcess.getProfit());
                sysGoodsProcess.setMagnification(submitGoodsProcess.getMagnification());
                sysGoodsProcess.setRemark(submitGoodsProcess.getRemark());
                sysGoodsProcess.setCreateBy(SecurityUtils.getUserId());
                sysGoodsProcess.setUpdateBy(SecurityUtils.getUserId());
                super.save(sysGoodsProcess);
            } else {
                // 已存在数据，则更新数据配置
                sysGoodsProcess.setProfit(submitGoodsProcess.getProfit());
                sysGoodsProcess.setMagnification(submitGoodsProcess.getMagnification());
                sysGoodsProcess.setRemark(submitGoodsProcess.getRemark());
                super.updateById(sysGoodsProcess);
            }

            // 更新工序明细数据
            this.goodsProcessItemService.submitGoodsProcessItems(sysGoodsProcess.getId(), submitGoodsProcess.getProcessItems());
        }
    }

    /**
     * 查询商品报价单部件工序信息
     *
     * @param partId
     * @return
     */
    @Override
    public GoodsQuotationSheetPartProcessDTO queryQuotationSheetPartProcesses(Long partId) {

        SysGoodsProcess sysGoodsProcess = super.getOne(new LambdaQueryWrapper<SysGoodsProcess>()
                .eq(SysGoodsProcess::getGoodsPartId, partId)
        );
        if (sysGoodsProcess == null) {
            // 初始化数据
            GoodsQuotationSheetPartProcessDTO goodsProcessVO = new GoodsQuotationSheetPartProcessDTO();
            goodsProcessVO.setTotalProcessCosts(null);

            // 设置默认利润率
            goodsProcessVO.setProfit("12.5");
            goodsProcessVO.setProcessingFee(null);
            goodsProcessVO.setMagnification(null);
            goodsProcessVO.setTotalLaborCost(null);
            goodsProcessVO.setProcessItems(new ArrayList<>());
            return goodsProcessVO;
        }


        List<GoodsQuotationSheetPartProcessDTO.ProcessItemVO> processItemVOS = this.goodsProcessItemService.list(new LambdaQueryWrapper<SysGoodsProcessItem>()
                .eq(SysGoodsProcessItem::getGoodsProcessId, sysGoodsProcess.getId())
        ).stream().map(x -> {
            GoodsQuotationSheetPartProcessDTO.ProcessItemVO processItemVO = new GoodsQuotationSheetPartProcessDTO.ProcessItemVO();
            processItemVO.setId(x.getId());
            processItemVO.setProcessName(x.getProcessName());
            processItemVO.setWage(x.getWage());
            processItemVO.setRemark(x.getRemark());
            return processItemVO;
        }).collect(Collectors.toList());


        // 计算工价合计
        BigDecimal totalLaborCost = processItemVOS.stream().map(x -> new BigDecimal(x.getWage())).reduce(BigDecimal.ZERO, BigDecimal::add);
//        totalLaborCost = NumberUtil.round(totalLaborCost, 2);

        // 倍率
        BigDecimal magnification = new BigDecimal(StrUtil.blankToDefault(sysGoodsProcess.getMagnification(), "0"));

        // 利润率
        BigDecimal profit = NumberUtil.div(StrUtil.blankToDefault(sysGoodsProcess.getProfit(), "0"), "100");

        // 计算加工费
        BigDecimal processingFee = NumberUtil.mul(totalLaborCost, magnification);

        // 计算工序费用合计
        BigDecimal totalProcessCosts = NumberUtil.mul(processingFee, NumberUtil.add(new BigDecimal(1), profit));

        GoodsQuotationSheetPartProcessDTO sheetPartProcessDTO = new GoodsQuotationSheetPartProcessDTO();
        sheetPartProcessDTO.setTotalProcessCosts(NumberUtil.round(totalProcessCosts,2).toPlainString());
        sheetPartProcessDTO.setProfit(sysGoodsProcess.getProfit());
        sheetPartProcessDTO.setProcessingFee(NumberUtil.round(processingFee,2).toPlainString());
        sheetPartProcessDTO.setMagnification(sysGoodsProcess.getMagnification());
        sheetPartProcessDTO.setTotalLaborCost(NumberUtil.round(totalLaborCost,2).toPlainString());
        sheetPartProcessDTO.setRemark(sysGoodsProcess.getRemark());
        sheetPartProcessDTO.setProcessItems(processItemVOS);
        return sheetPartProcessDTO;
    }
}
